-module(generic_algo_lib).

%%-export([record_to_json/2,pfoldr/3,to_integer/2,rand/2,for/3,mergezip/2,record_format/2]).
-compile(export_all).


%%并行版本的lists:folder
pfoldr(F,Acc,L)->

    S=self(),
    Ref=erlang:make_ref(),

    lists:foreach(fun(E) -> spawn(fun() -> do_f(S,Ref,F,E) end) end, L),
    gather(length(L),Ref,Acc).

do_f(Parent,Ref,F,E) ->
    Parent!{Ref,(catch F(E))}.

gather(0, _, L) -> 
    L;
gather(N, Ref,L) ->
    receive
	{Ref,Ret} ->
	    gather(N-1,Ref,[Ret|L])
    end.

%%转换为整数
to_integer(N,D) ->
    try string:to_integer(N) of
	{error,_} -> D;
	{Num,_} -> Num
    catch
	_:_ ->
	    D
    end.

rand(Max,Max)->
    Max;	
rand(Min,Max) ->
    try 
        crypto:start(),
        crypto:rand_uniform(Min, Max)
    catch
        _ ->
        0
    end.

list_set_value(List, 0, _NewValue) when is_list(List) ->
    List;
list_set_value(List, Pos, NewValue) when is_list(List) ->
    list_set_value(List, Pos, NewValue, []).

list_set_value([_Head|Rest], 1, NewValue, Acc) ->
    lists:reverse(Acc) ++ [NewValue] ++ Rest;
list_set_value([Head|Rest], Pos, NewValue, Acc) ->
    list_set_value(Rest, Pos-1, NewValue, [Head|Acc]).

for(Max,Max,F) -> [F(Max)];
for(I,Max,F) -> [F(I)|for(I+1,Max,F)].

mergezip(L1, L2) when is_list(L1),is_list(L2) ->
    mergezip(L1,L1,0,L2,L2,0,[]).

mergezip([H1|R1],L1,N1,[H2|R2],L2,N2,Z) ->
    mergezip(R1,L1,N1,R2,L2,N2,[{H1,H2}|Z]);
mergezip([],_L1,_N1,[],_L2,_N2,Z) ->
    lists:reverse(Z);
mergezip(R1,L1,0,[],L2,N2,Z) ->
    mergezip(R1,L1,0,L2,L2,N2+1,Z);
mergezip(_R1,_L1,_N1,[],_L2,_N2,Z) ->
    lists:reverse(Z);
mergezip([],L1,N1,R2,L2,0,Z) ->
    mergezip(L1,L1,N1+1,R2,L2,0,Z);
mergezip([],_L1,_N1,_R2,_L2,_N2,Z) ->
    lists:reverse(Z).

merge(L1,L2) when is_list(L1),is_list(L2) ->
    merge(L1,L2,[]).

merge([],L2,Z) ->
    lists:reverse(Z) ++ L2;
merge(L1,[],Z) ->
    lists:reverse(Z) ++ L1;
merge([H1|R1],[H2|R2],Z) ->
    if
	H1 =< H2 ->
	    merge(R1,[H2|R2],[H1|Z]);
	true ->
	    merge([H1|R1],R2,[H2|Z])
    end.

%%随机化一个链表
shuffle_v1(L) -> 
    List1 = [{random:uniform(), X} || X <- L],
    List2 = lists:keysort(1, List1),
    [E || {_, E} <- List2].    

getExtRegex(Base,Ext) ->
    %%io:format("~p~n",[{Base,Ext}]),
    [Head|Rest] = string:tokens(Base,"_"),

    ExtName = 
	case length(Ext) of
	    0 ->
		[];
	    _ ->
		"." ++ Ext
	end,

    BaseName =
	case length(Rest) of
	    0 ->
		Head ++ "*";
	    _ ->
		Head ++ "_*"
	end,
    "http://" ++ BaseName ++ ExtName.

%%无法处理blog.xiaonei.com或blog.xiaonei.com/forum/1000这类的url，即没有扩展名的url
getExtRegex(Res) ->
    %%io:format("~p~n",[Res]),
    try
	case length(Res) of
	    1 ->
		Columns = string:tokens(lists:nth(1,Res),"/"),
		%%io:format("~p~n",[Columns]),
		[Base,Ext] = string:tokens(lists:nth(length(Columns),Columns),"."),
		%%io:format("~p~n",[{Base,Ext}]),
		Root = lists:sublist(Columns,length(Columns)-1) ++ [Base],
		%%io:format("~p~n",[Root]),
		getExtRegex(string:join(Root,"/"),Ext);
	    _ ->
		[]
	end
    catch
	X:Y ->
	    {X,Y}
    end.

getDomainAndExtname(Url) when is_list(Url) ->
    [_,Root|_] = string:tokens(Url, "/"),
    Domain = "http://" ++ Root,
    [_Http|Res] = re:split(Url,"//",[{return,list}]),
    {Domain,getExtRegex2(Res)}.


%%another getExtRegex implenment
getExtRegex2(Res) ->
    %%io:format("~p~n",[Res]),
    try
	case length(Res) of
	    1 ->
		[Head|Rest] = All = re:split(lists:nth(1,Res),"(/.*)\\.",[{return,list}]),
		case length(Rest) of
		    0 ->
			getExtRegex(Head,[]);
		    _ ->
			Root = lists:sublist(All, length(All)-1),
			getExtRegex(string:join(Root,""), lists:nth(length(All),All) )
		end;
	    _ ->
		[]
	end
    catch
	X:Y ->
	    {X,Y}
    end.
